package orange.com.openstack.sahara;

import orange.com.openstack.api.Authentications;
import orange.com.openstack.sahara.api.ClusterTemplates;
import orange.com.openstack.sahara.api.Clusters;
import orange.com.openstack.sahara.api.DataSources;
import orange.com.openstack.sahara.api.Images;
import orange.com.openstack.sahara.api.JobBinaries;
import orange.com.openstack.sahara.api.JobBinaryInternals;
import orange.com.openstack.sahara.api.JobExecutions;
import orange.com.openstack.sahara.api.Jobs;
import orange.com.openstack.sahara.api.NodeGroupTemplates;
import orange.com.openstack.sahara.api.Plugins;
import orange.com.openstack.swift.Uploader;

import org.javaswift.joss.model.StoredObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author osvaldo.cocucci@gmail.com
 * 
 */
public class Client {

	public static Logger logger = LoggerFactory.getLogger(Client.class);;
	private String username;
	private String password;
	private String endpoint;
	private String tenantName;
	Uploader swiftUploader;
	Authentications authentications;
	JobBinaries jobBinaries;
	DataSources dataSources;
	JobBinaryInternals jobBinaryInternals;
	JobExecutions jobExecutions;
	Jobs jobs;
	Clusters clusters;
	ClusterTemplates clusterTemplates;
	Images images;
	NodeGroupTemplates nodeGroupTemplates;
	Plugins plugins;

	public Client(String username, String password, String endpoint,
			String tenantName) {
		super();
		this.username = username;
		this.password = password;
		this.endpoint = endpoint;
		this.tenantName = tenantName;

		swiftUploader = new Uploader(username, password, tenantName, endpoint
				+ ":5000/v2.0/tokens");
		authentications = new Authentications(endpoint + ":5000/v2.0/tokens",
				username, tenantName, password);
		dataSources = new DataSources(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		jobBinaries = new JobBinaries(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		jobBinaryInternals = new JobBinaryInternals(endpoint + ":8386/v1.1/",
				authentications.getAuthenticationToken().getTenantId(),
				authentications.getAuthenticationToken().getToken());
		jobExecutions = new JobExecutions(endpoint + ":8386/v1.1/",
				authentications.getAuthenticationToken().getTenantId(),
				authentications.getAuthenticationToken().getToken());
		jobs = new Jobs(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		clusters = new Clusters(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		clusterTemplates= new ClusterTemplates(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		images = new Images(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		nodeGroupTemplates = new NodeGroupTemplates(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());
		plugins = new Plugins(endpoint + ":8386/v1.1/", authentications
				.getAuthenticationToken().getTenantId(), authentications
				.getAuthenticationToken().getToken());

	}

	public static void main(String[] args) {

		logger.info("running client");
		// Check how many arguments were passed in
		if (args.length < 4) {
			System.out
					.println("Proper Usage is with 4 arguments: <username> <password> <endpoint> <tenantName>");
			System.out.println("e.g: admin myPass http://myIP admin");
			System.exit(0);
		}
		Client client = new Client(args[0], args[1], args[2], args[3]);

		String libsContainer = "LIBSCONTAINERNAME";
		// String inputContainer = "INPUTCONTAINERNAME";
		String outputContainer = "OUTPUTCONTAINERNAME";
		// ////////////////////////////////////////uploading jars //
		// ////////////////////////////////////////////

		client.getSwiftUploader().upload("PATH2MYFILE", libsContainer);
		StoredObject gson = client.getSwiftUploader().upload(
				"c:/PATH2MYLIBFOLDER/MYJAR.jar", libsContainer);

		// create the output container
		client.getSwiftUploader().createContainer(outputContainer);

		// ////////////////////////////////////////authenticate on sahara //
		// ////////////////////////////////////////////
		System.out.println("token from authentication = "
				+ client.getAuthentications().getAuthenticationToken()
						.getToken());
		// //////////////////////////////////////// create the jobBinaries //
		// ////////////////////////////////////////////

		String gsonId;

		if (!client.getJobBinaries().exist(gson.getName()))
			gsonId = client
					.getJobBinaries()
					.createJobBinaries(gson.getName(),
							"swift://" + libsContainer + "/" + gson.getName(),
							args[1], args[0], "Swift", gson.getName()).getId();
		else
			gsonId = client.getJobBinaries().getId(gson.getName());

		// //////////////////////////////////////// create the job //
		// ////////////////////////////////////////////
		String jobId;
		Jobs job = client.getJobs();
		if (!job.exist("MYJOBNAME"))
			jobId = job.createJob("MYJOBNAME", new String[] {},
					new String[] { "\"" + gsonId + "\"" }, "Java", "MYJOBNAME")
					.getId();
		else
			jobId = job.getId("MYJOBNAME");

		// ////////////////////////////////////////create execution status //
		// ////////////////////////////////////////////

		JobExecutions exec = client.getJobExecutions();
		System.out.println(exec.showJobExecutionStatus(jobId));

	}

	public Uploader getSwiftUploader() {
		return swiftUploader;
	}

	public void setSwiftUploader(Uploader swiftUploader) {
		this.swiftUploader = swiftUploader;
	}

	public JobBinaries getJobBinaries() {
		return jobBinaries;
	}

	public void setJobBinaries(JobBinaries jobBinaries) {
		this.jobBinaries = jobBinaries;
	}

	public DataSources getDataSources() {
		return dataSources;
	}

	public void setDataSources(DataSources dataSources) {
		this.dataSources = dataSources;
	}

	public JobBinaryInternals getJobBinaryInternals() {
		return jobBinaryInternals;
	}

	public void setJobBinaryInternals(JobBinaryInternals jobBinaryInternals) {
		this.jobBinaryInternals = jobBinaryInternals;
	}

	public JobExecutions getJobExecutions() {
		return jobExecutions;
	}

	public void setJobExecutions(JobExecutions jobExecutions) {
		this.jobExecutions = jobExecutions;
	}

	public Jobs getJobs() {
		return jobs;
	}

	public void setJobs(Jobs jobs) {
		this.jobs = jobs;
	}

	public Authentications getAuthentications() {
		return authentications;
	}

	public void setAuthentications(Authentications authentications) {
		this.authentications = authentications;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEndpoint() {
		return endpoint;
	}

	public void setEndpoint(String endpoint) {
		this.endpoint = endpoint;
	}

	public String getTenantName() {
		return tenantName;
	}

	public void setTenantName(String tenantName) {
		this.tenantName = tenantName;
	}

	public Clusters getClusters() {
		return clusters;
	}

	public void setClusters(Clusters clusters) {
		this.clusters = clusters;
	}

	public ClusterTemplates getClusterTemplates() {
		return clusterTemplates;
	}

	public void setClusterTemplates(ClusterTemplates clusterTemplates) {
		this.clusterTemplates = clusterTemplates;
	}

	public Images getImages() {
		return images;
	}

	public void setImages(Images images) {
		this.images = images;
	}

	public NodeGroupTemplates getNodeGroupTemplates() {
		return nodeGroupTemplates;
	}

	public void setNodeGroupTemplates(NodeGroupTemplates nodeGroupTemplates) {
		this.nodeGroupTemplates = nodeGroupTemplates;
	}

	public Plugins getPlugins() {
		return plugins;
	}

	public void setPlugins(Plugins plugins) {
		this.plugins = plugins;
	}
}
